//------------------------------------------------------------------------------
//	file midi_ports.c
//	brief
//		Display all midi port information
//
//	$Id: midi_ports.c 3 2014-04-19 07:10:51Z ac.verbeck@gmail.com $
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Copyright and Disclaimer Notice
//
//	The MIT License (MIT)
//	
//	Copyright (c) 2014 A.C. Verbeck
//	
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//	
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//	
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.
//
//------------------------------------------------------------------------------

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#include <stdint.h>																//	Standard int types
#include <stdbool.h>															//	Bool

#include <Windows.h>
#include <mmsystem.h>

//------------------------------------------------------------------------------
//  Display information on all MIDI input devices
//
//  szPname:
//      Product name in a null-terminated string.
//
//  wMid:
//      Manufacturer identifier of the device driver for the MIDI output device.
//      Manufacturer identifiers are defined in Manufacturer and Product Identifiers.
//
//  wPid:
//      Product identifier of the MIDI output device.
//      Product identifiers are defined in Manufacturer and Product Identifiers.
//
//  vDriverVersion:
//      Version number of the device driver for the MIDI output device.
//      The high-order byte is the major version number,
//      the low-order byte is the minor version number.
//
//------------------------------------------------------------------------------
static void dispMidiInDevs(void)
{
	UINT nMidiDeviceNum;
	MIDIINCAPS caps;

	nMidiDeviceNum = midiInGetNumDevs();
	if (nMidiDeviceNum == 0) {
		printf("No MIDI input ports\n");
		return;
	}
	printf("MIDI input ports:\n");
	printf(" %s %-32s %-4s %-4s %-4s\n","id","name","man","prod","ver");
	for (unsigned int i = 0; i < nMidiDeviceNum; ++i) {
		midiInGetDevCaps(i, &caps, sizeof(MIDIINCAPS));
		printf("  %d %-32s ", i, caps.szPname);
		printf("%04x %04x %04x", caps.wMid, caps.wPid, caps.vDriverVersion);
		printf("\n");
	}
	printf("\n");
}

//------------------------------------------------------------------------------
//  Display information on all MIDI output devices
//
//  szPname:
//      Product name in a null-terminated string.
//
//  wMid:
//      Manufacturer identifier of the device driver for the MIDI output device.
//      Manufacturer identifiers are defined in Manufacturer and Product Identifiers.
//
//  wPid:
//      Product identifier of the MIDI output device.
//      Product identifiers are defined in Manufacturer and Product Identifiers.
//
//  vDriverVersion:
//      Version number of the device driver for the MIDI output device.
//      The high-order byte is the major version number,
//      the low-order byte is the minor version number.
//
//  wTechnology:
//      Type of the MIDI output device (enum)
//
//  Voices:
//      Number of voices supported by an internal synthesizer device.
//      If the device is a port, this member is not meaningful and is set to 0.
//
//  wNotes:
//      Maximum number of simultaneous notes that can be played
//      by an internal synthesizer device.
//      If the device is a port, this member is not meaningful and is set to 0.
//
//  wChannelMask:
//      Channels that an internal synthesizer device responds to,
//      where the least significant bit refers to channel 0
//      and the most significant bit to channel 15.
//      Port devices that transmit on all channels set this member to 0xFFFF.
//
//------------------------------------------------------------------------------
static void dispMidiOutDevs(void)
{
	UINT nMidiDeviceNum;
	MIDIOUTCAPS caps;

	nMidiDeviceNum = midiOutGetNumDevs();
	if (nMidiDeviceNum == 0) {
		printf("No MIDI output ports\n");
		return;
	}
	printf("MIDI output ports:\n");
	printf(" %s %-32s %-4s %-4s %-4s %-4s %-4s %-4s %-4s\n","id","name","man","prod","ver","tech","vocs","note", "mask");
	for (unsigned int i = 0; i < nMidiDeviceNum; ++i) {
		midiOutGetDevCaps(i, &caps, sizeof(MIDIINCAPS));
		printf("  %d %-32s ", i, caps.szPname);
		printf("%04x %04x %04x ", caps.wMid, caps.wPid, caps.vDriverVersion);
		printf("%04x %04x %04x %04x", caps.wTechnology, caps.wVoices, caps.wNotes, caps.wChannelMask);
		printf("\n");
	}
	printf("\n");
}

//------------------------------------------------------------------------------
//  Main application
//  - Print information on the MIDI input ports
//  - Print information on the MIDI output ports
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
	dispMidiInDevs();
	dispMidiOutDevs();
	return 0;
}

//
//  End: midi_ports.c
//
